package com.uidp.security;

import static java.security.MessageDigest.getInstance;

import java.security.MessageDigest;

import org.apache.geronimo.crypto.encoders.Hex;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

/**
 * Клас за хеширане на низове, прилага SHA1 и MD5 хеширане.
 * 
 */
public class Digester {

	/** MD5 хеширане. */
	private static final String MD5 = "MD5";

	/** SHA хеширане. */
	private static final String SHA = "SHA";

	/** {SHA}. */
	private static final String SHA_PREFIX = "{" + SHA + "}";

	/** SHA-1 хеширане. */
	private static final String SHA1 = "SHA-1";

	/** UTF-8 кодиране. */
	private static final String UTF_ENCODING = "UTF-8";

	/**
	 * По base 64 encoded входен низ прави MD5 хеширане и връща base 64 encoded
	 * резултат.
	 * 
	 * @param message
	 *            - входен низ
	 * 
	 * @return {SHA} + хешираното съобщение или входния низ при възникнало
	 *         изключение
	 */
	public static String digestMD5Encoded(String message) {
		try {
			MessageDigest md = getInstance(MD5);
			md.update(new BASE64Decoder().decodeBuffer(message));
			return SHA_PREFIX + new BASE64Encoder().encode(md.digest());
		} catch (Exception e) {
			return message;
		}
	}

	/**
	 * По входен низ прави SHA1 + MD5 хеширане и връща base 64 encoded резултат.
	 * 
	 * @param message
	 *            - входен низ
	 * 
	 * @return {SHA} + хешираното съобщение или входния низ при възникнало
	 *         изключение
	 */
	public static String digestMessage(String message) {
		try {
			MessageDigest md = getInstance(SHA);
			md.update(message.getBytes(UTF_ENCODING));
			byte[] bytes = md.digest();
			md = getInstance(MD5);
			md.update(bytes);
			return SHA_PREFIX + new BASE64Encoder().encode(md.digest());
		} catch (Exception e) {
			return message;
		}
	}

	/**
	 * По входен низ прави MD5 хеширане и връща base 64 encoded резултат.
	 * 
	 * @param message
	 *            - входен низ
	 * 
	 * @return {SHA} + хешираното съобщение или входния низ при възникнало
	 *         изключение
	 */
	public static String digestSHA(String message) {
		try {
			MessageDigest md = getInstance(SHA);
			md.update(message.getBytes(UTF_ENCODING));
			return new BASE64Encoder().encode(md.digest());
		} catch (Exception e) {
			return message;
		}
	}

	/**
	 * По подаден входен низ връща SHA-1 криптираното му съответствие.
	 * 
	 * @param message
	 *            - входен низ
	 * 
	 * @return {SHA} + хешираното съобщение или входния низ при възникнало
	 *         изключение
	 */
	public static String digestSHA1(String message) {
		try {
			MessageDigest md = getInstance(SHA1);
			md.reset();
			md.update(message.getBytes(UTF_ENCODING));
			return new String(Hex.encode(md.digest()));
		} catch (Exception e) {
			return message;
		}
	}

}